﻿using System;
using System.Collections.Generic;

using Microsoft.WowAddonStudio.Lua.Model;
using Microsoft.WowAddonStudio.Lua.Parser;

namespace Microsoft.WowAddonStudio.Lua.AST
{
    /// <summary>
    /// Represents a function as a statement (declaration)
    /// in the AST for the Lua code file.
    /// </summary>
    public class FunctionDeclaration : Statement
    {
        /// <summary>
        /// Initializes a new instance of the <see cref="Function"/> class.
        /// </summary>
        /// <param name="location">The location of the node.</param>
        public FunctionDeclaration(LexLocation location)
            : base(location)
        {
        }

		/// <summary>
		/// Gets or sets the qualified name of the function.
		/// </summary>
		/// <value>The name.</value>
        public QualifiedName FunctionName { get; set; }

		/// <summary>
		/// Gets or sets the parameter list.
		/// </summary>
		/// <value>The parameter list.</value>
        public ParameterList ParameterList { get; set; }

		/// <summary>
		/// Gets or sets the function body.
		/// </summary>
		/// <value>The body.</value>
        public Block Body { get; set; }

		/// <summary>
		/// Gets or sets whether the function was declared local in its scope.
		/// </summary>
		/// <value><c>true</c> if this instance is local; otherwise, <c>false</c>.</value>
        public bool IsLocal { get; set; }

        /// <summary>
        /// Gets the inner scope of the function declaration.
        /// </summary>
        public Scope InnerScope
        {
            get
            {
                return this.Body != null ? this.Body.Scope : null;
            }
        }

        /// <summary>
        /// Gets an enumerable collection of the parameter <see cref="Identifier"/>s.
        /// </summary>
        /// <returns>An enumerable collection of <see cref="Identifier"/>s.</returns>
        public IEnumerable<Identifier> GetParameterIdentifiers()
        {
            if (ParameterList != null && ParameterList.IdentifierList != null)
            {
                foreach (Identifier identifier in ParameterList.IdentifierList)
                    yield return identifier;
            }
        }

        /// <summary>
        /// Gets the child nodes of the node.
        /// </summary>
        /// <returns>An enumerable collection of nodes.</returns>
        public override IEnumerable<Node> GetChildNodes()
        {
            yield return ParameterList;
            yield return Body;
        }

        /// <summary>
        /// Returns a <see cref="T:System.String"/> that represents the current <see cref="T:System.Object"/>.
        /// </summary>
        /// <returns>
        /// A <see cref="T:System.String"/> that represents the current <see cref="T:System.Object"/>.
        /// </returns>
        public override string ToString()
        {
            return String.Format("FunctionDeclaration [Name = {0}, IsLocal = {1}]", this.FunctionName, this.IsLocal);
        }
	}
}
